/**
 * Reusable chart data fetching logic for Svelte components.
 *
 * Eliminates duplicate code across LineChart, PieChart, GaugeChart, BoxplotChart.
 *
 * Usage:
 * ```svelte
 * <script>
 *   import { useChartData } from '../utils/useChartData.js';
 *
 *   export let endpoint = "";
 *   export let authToken = "";
 *   export let polling = 0;
 *   export let data = null;
 *
 *   const { loading, error, fetchData, cleanup } = useChartData();
 *
 *   onMount(() => {
 *     if (data) {
 *       renderChart(data);
 *     } else if (endpoint) {
 *       fetchData(endpoint, authToken, polling, renderChart);
 *     }
 *   });
 *
 *   onDestroy(cleanup);
 * </script>
 * ```
 */

import { writable } from 'svelte/store';

export function useChartData() {
  const loading = writable(true);
  const error = writable('');

  let abortController = null;
  let pollingTimer = null;

  /**
   * Fetch data from API endpoint with optional polling.
   *
   * @param {string} endpoint - API endpoint URL
   * @param {string} authToken - Bearer token for authentication
   * @param {number} pollingInterval - Polling interval in milliseconds (0 = no polling)
   * @param {function} onSuccess - Callback function to render chart with fetched data
   */
  async function fetchData(endpoint, authToken = '', pollingInterval = 0, onSuccess) {
    if (!endpoint) {
      loading.set(false);
      error.set('Missing endpoint');
      return;
    }

    // Cancel previous request
    if (abortController) {
      abortController.abort();
    }
    abortController = new AbortController();

    try {
      const headers = new Headers({ 'Accept': 'application/json' });
      if (authToken) {
        headers.set('Authorization', `Bearer ${authToken}`);
      }

      const response = await fetch(endpoint, {
        headers,
        signal: abortController.signal
      });

      if (!response.ok) {
        throw new Error(`Request failed: ${response.status} ${response.statusText}`);
      }

      const responseData = await response.json();

      loading.set(false);
      error.set('');

      // Call success callback to render chart
      if (onSuccess) {
        onSuccess(responseData);
      }

      // Setup polling if interval > 0
      if (pollingInterval > 0) {
        pollingTimer = setTimeout(() => {
          fetchData(endpoint, authToken, pollingInterval, onSuccess);
        }, pollingInterval);
      }

    } catch (err) {
      // Ignore abort errors (normal during cleanup)
      if (err.name === 'AbortError') {
        return;
      }

      loading.set(false);
      error.set(err.message || 'Failed to fetch data');
      console.error('[useChartData] Fetch error:', err);
    }
  }

  /**
   * Cleanup function to cancel pending requests and timers.
   * Call this in onDestroy() lifecycle hook.
   */
  function cleanup() {
    if (abortController) {
      abortController.abort();
      abortController = null;
    }
    if (pollingTimer) {
      clearTimeout(pollingTimer);
      pollingTimer = null;
    }
  }

  return {
    loading,
    error,
    fetchData,
    cleanup
  };
}

/**
 * Create authorization header object.
 *
 * @param {string} token - Bearer token
 * @returns {object} Headers object with Authorization
 */
export function createAuthHeaders(token) {
  const headers = new Headers({ 'Accept': 'application/json' });
  if (token) {
    headers.set('Authorization', `Bearer ${token}`);
  }
  return headers;
}

/**
 * Handle fetch errors with consistent error messages.
 *
 * @param {Error} err - Error object
 * @param {string} context - Context string for logging
 * @returns {string} User-friendly error message
 */
export function handleFetchError(err, context = 'API') {
  if (err.name === 'AbortError') {
    return null; // Silently ignore abort errors
  }

  const message = err.message || 'Unknown error';
  console.error(`[${context}] Fetch error:`, err);

  // Map common errors to user-friendly messages
  if (message.includes('401')) {
    return 'Authentication failed. Please log in again.';
  }
  if (message.includes('403')) {
    return 'Access denied. You do not have permission.';
  }
  if (message.includes('404')) {
    return 'Resource not found.';
  }
  if (message.includes('500')) {
    return 'Server error. Please try again later.';
  }
  if (message.includes('NetworkError') || message.includes('Failed to fetch')) {
    return 'Network error. Please check your connection.';
  }

  return `${context} error: ${message}`;
}
